package com.library.service.impl;

import com.library.dto.BookDTO;
import com.library.entity.Book;
import com.library.entity.BorrowRecord;
import com.library.mapper.BookMapper;
import com.library.mapper.BorrowRecordMapper;
import com.library.service.BookService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;
    
    @Autowired
    private BorrowRecordMapper borrowRecordMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String BOOK_CACHE_PREFIX = "book:";
    private static final String BOOKS_CACHE_KEY = "books:all";
    private static final long CACHE_EXPIRE_MINUTES = 5;

    @Override
    public List<Book> getAllBooks() {
        // 先从缓存中获取
        List<Book> books = (List<Book>) redisTemplate.opsForValue().get(BOOKS_CACHE_KEY);
        if (books != null) {
            return books;
        }
        
        // 缓存中没有，从数据库获取
        books = bookMapper.findAll();
        
        // 存入缓存
        redisTemplate.opsForValue().set(BOOKS_CACHE_KEY, books, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        
        return books;
    }

    @Override
    public Book getBookById(Long id) {
        String cacheKey = BOOK_CACHE_PREFIX + id;
        Book book = (Book) redisTemplate.opsForValue().get(cacheKey);
        if (book != null) {
            return book;
        }
        
        book = bookMapper.findById(id);
        if (book != null) {
            redisTemplate.opsForValue().set(cacheKey, book, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        }
        
        return book;
    }

    @Override
    public Book getBookByIsbn(String isbn) {
        return bookMapper.findByIsbn(isbn);
    }

    @Override
    public List<Book> searchBooks(String keyword) {
        return bookMapper.searchBooks(keyword);
    }

    @Override
    @Transactional
    public Book addBook(BookDTO bookDTO) {
        Book book = new Book();
        BeanUtils.copyProperties(bookDTO, book);
        book.setAvailableStock(book.getStock());
        
        bookMapper.insert(book);
        
        // 清除缓存
        clearCache();
        
        return book;
    }

    @Override
    @Transactional
    public Book updateBook(Long id, BookDTO bookDTO) {
        Book existingBook = bookMapper.findById(id);
        if (existingBook == null) {
            throw new RuntimeException("图书不存在");
        }
        
        BeanUtils.copyProperties(bookDTO, existingBook);
        existingBook.setId(id);
        
        // 确保可用库存不超过总库存
        if (existingBook.getAvailableStock() > existingBook.getStock()) {
            existingBook.setAvailableStock(existingBook.getStock());
        }
        
        bookMapper.update(existingBook);
        
        // 清除缓存
        clearCache();
        
        return existingBook;
    }

    @Override
    @Transactional
    public void deleteBook(Long id) {
        bookMapper.deleteById(id);
        clearCache();
    }

    @Override
    @Transactional
    public boolean borrowBook(Long bookId, String borrowerName, String borrowerContact) {
        Book book = bookMapper.findById(bookId);
        if (book == null || book.getAvailableStock() <= 0) {
            return false;
        }
        
        // 更新库存
        bookMapper.updateStock(bookId, -1);
        
        // 创建借阅记录
        BorrowRecord record = new BorrowRecord();
        record.setBookId(bookId);
        record.setBorrowerName(borrowerName);
        record.setBorrowerContact(borrowerContact);
        record.setBorrowTime(LocalDateTime.now());
        record.setDueTime(LocalDateTime.now().plusDays(30));
        record.setStatus(0);
        
        borrowRecordMapper.insert(record);
        
        // 清除缓存
        clearCache();
        
        return true;
    }

    @Override
    @Transactional
    public boolean returnBook(Long borrowRecordId) {
        BorrowRecord record = borrowRecordMapper.findById(borrowRecordId);
        if (record == null || record.getStatus() != 0) {
            return false;
        }
        
        // 更新借阅记录状态
        borrowRecordMapper.updateStatus(borrowRecordId, 1);
        
        // 增加图书可用库存
        bookMapper.updateStock(record.getBookId(), 1);
        
        // 清除缓存
        clearCache();
        
        return true;
    }
    
    private void clearCache() {
        redisTemplate.delete(BOOKS_CACHE_KEY);
        // 注意：这里不删除单个图书缓存，因为可能有多个图书被更新
    }
}
